package sysTask

import (
	"bytes"
	"context"
	"donkey-admin/internal/consts"
	"donkey-admin/internal/model/entity"
	customclient "donkey-admin/utility/systask/utils/httpclient"
	"fmt"
	"github.com/gogf/gf/v2/frame/g"
	"net/http"
	"os/exec"
)

// Handler 任务处理程序
type Handler interface {
	Run(ctx context.Context, taskModel entity.SysTask, sysTaskLogId string) (string, error)
}

// ShellHandler Shell任务
type ShellHandler struct{}

// Run 执行Shell任务
func (h *ShellHandler) Run(ctx context.Context, taskModel entity.SysTask, sysTaskLogId string) (result string, err error) {
	g.Log().Info(ctx, "==========执行内部Shell的生成逻辑==========")
	shellPath := taskModel.InvokeTarget

	// 创建命令
	cmd := exec.Command("sh", "-c", shellPath)

	// 获取标准输出和标准错误管道
	var stdout, stderr bytes.Buffer
	cmd.Stdout = &stdout
	cmd.Stderr = &stderr

	// 启动命令
	if err = cmd.Start(); err != nil {
		g.Log().Error(ctx, fmt.Sprintf("启动命令失败: %s", err))
		return "", err
	}

	// 等待命令完成
	if err = cmd.Wait(); err != nil {
		g.Log().Error(ctx, fmt.Sprintf("命令执行失败: %s\n标准错误: %s", err, stderr.String()))
		return "", err
	}

	// 获取命令的输出结果
	output := stdout.String()
	g.Log().Info(ctx, "命令输出: "+output)
	return output, nil
}

// HTTPHandler HTTP任务
type HTTPHandler struct{}

func (h *HTTPHandler) Run(ctx context.Context, taskModel entity.SysTask, sysTaskLogId string) (result string, err error) {
	if taskModel.Timeout <= 0 || taskModel.Timeout > consts.HttpExecTimeout {
		taskModel.Timeout = consts.HttpExecTimeout
	}
	var resp customclient.ResponseWrapper
	// 返回状态码非200，均为失败
	switch taskModel.HttpMethod {
	case consts.TaskHTTPMethodGet:
		resp = customclient.Get(taskModel.InvokeTarget, taskModel.Timeout)
	case consts.TaskHTTPMethodPost:
		resp = customclient.PostJson(taskModel.InvokeTarget, taskModel.Args, taskModel.Timeout)
	default:
		g.Log().Info(ctx, "暂时还没有其他method类型，可自行添加")
	}
	if resp.StatusCode != http.StatusOK {
		g.Log().Error(ctx, "[ERROR] http request failed! ", err)
		return resp.Body, fmt.Errorf("HTTP状态码非200-->%d", resp.StatusCode)
	}

	return resp.Body, err
}

// InternalFuncHandler 内部函数任务
type InternalFuncHandler struct{}

func (h *InternalFuncHandler) Run(ctx context.Context, taskModel entity.SysTask, sysTaskLogId string) (result string, err error) {
	g.Log().Info(ctx, "==========执行内部函数的生成逻辑==========")

	var obj = JobList[taskModel.InvokeTarget]
	if obj == nil {
		g.Log().Warning(ctx, "[Job] ExecJob Run job nil, invokeTarget: "+taskModel.InvokeTarget)
		return
	}
	err = CallExec(ctx, obj.(JobExec), taskModel.Args)
	if err != nil {
		// 如果失败暂停一段时间重试
		g.Log().Error(ctx, " [ERROR] mission failed! ", err)
		result = err.Error()
	} else {
		result = "success"
	}
	return result, err
}
